home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / ar / archiver.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  14KB  |  745 lines

  1. /*
  2.  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3.  * See the copyright notice in the file "../Copyright".
  4.  */
  5. /* ar - archiver        Author: Michiel Huisjes */
  6. /* Made into arch/aal by Ceriel Jacobs
  7.  */
  8.  
  9. static char RcsId[] = "$Header: archiver.c,v 1.11 87/08/24 09:13:31 ceriel Exp $";
  10.  
  11. /*
  12.  * Usage: [arch|aal] [adprtvx] archive [file] ...
  13.  *      v: verbose
  14.  *      x: extract
  15.  *      a: append
  16.  *      r: replace (append when not in archive)
  17.  *      d: delete
  18.  *      t: print contents of archive
  19.  *      p: print named files
  20.  *      l: temporaries in current directory instead of /tmp
  21.  *      c: don't give "create" message
  22. #ifdef DISTRIBUTION
  23.  *      D: make distribution: use distr_time, uid=2, gid=2, mode=0644
  24. #endif
  25.  */
  26.  
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #include <signal.h>
  30. #include <arch.h>
  31. #ifdef AAL
  32. #include <ranlib.h>
  33. #include <out.h>
  34. #define MAGIC_NUMBER    AALMAG
  35. long    offset;
  36. struct ranlib *tab;
  37. long    tnum = 0;
  38. char    *tstrtab;
  39. long    tssiz = 0;
  40. char    *malloc(), *realloc(), *strcpy(), *strncpy();
  41. long    lseek();
  42. long    time();
  43. unsigned int tabsz, strtabsz;
  44. #else
  45. #define MAGIC_NUMBER    ARMAG
  46. #endif
  47.  
  48. #define odd(nr)        (nr & 01)
  49. #define even(nr)    (odd(nr) ? nr + 1 : nr)
  50.  
  51. typedef char BOOL;
  52. #define FALSE        0
  53. #define TRUE        1
  54.  
  55. #define READ        0
  56. #define APPEND        2
  57. #define CREATE        1
  58.  
  59. #define MEMBER        struct ar_hdr
  60.  
  61. #define NIL_PTR        ((char *) 0)
  62. #define NIL_MEM        ((MEMBER *) 0)
  63. #define NIL_LONG    ((long *) 0)
  64.  
  65. #define IO_SIZE        (10 * 1024)
  66.  
  67. #define equal(str1, str2)    (!strncmp((str1), (str2), 14))
  68.  
  69. BOOL verbose;
  70. BOOL app_fl;
  71. BOOL ex_fl;
  72. BOOL show_fl;
  73. BOOL pr_fl;
  74. BOOL rep_fl;
  75. BOOL del_fl;
  76. BOOL nocr_fl;
  77. BOOL local_fl;
  78. #ifdef DISTRIBUTION
  79. BOOL distr_fl;
  80. long distr_time;
  81. #endif
  82.  
  83. int ar_fd;
  84.  
  85. char io_buffer[IO_SIZE];
  86.  
  87. char *progname;
  88.  
  89. char temp_buf[32];
  90. char *temp_arch = &temp_buf[0];
  91. extern char *mktemp();
  92. extern char *ctime();
  93.  
  94. usage()
  95. {
  96.     error(TRUE, "usage: %s %s archive [file] ...\n",
  97.         progname,
  98. #ifdef AAL
  99.         "[acdrtxvl]"
  100. #else
  101.         "[acdprtxvl]"
  102. #endif
  103.         );
  104. }
  105.  
  106. /*VARARGS2*/
  107. error(quit, str1, str2, str3, str4)
  108. BOOL quit;
  109. char *str1, *str2, *str3, *str4;
  110. {
  111.     char errbuf[256];
  112.  
  113.     sprintf(errbuf, str1, str2, str3, str4);
  114.     write(2, errbuf, strlen(errbuf));
  115.       if (quit) {
  116.         unlink(temp_arch);
  117.         exit(1);
  118.       }
  119. }
  120.  
  121. char *basename(path)
  122. char *path;
  123. {
  124.   register char *ptr = path;
  125.   register char *last = NIL_PTR;
  126.  
  127.   while (*ptr != '\0') {
  128.     if (*ptr == '/')
  129.         last = ptr;
  130.     ptr++;
  131.   }
  132.   if (last == NIL_PTR)
  133.     return path;
  134.   if (*(last + 1) == '\0') {
  135.     *last = '\0';
  136.     return basename(path);
  137.   }
  138.   return last + 1;
  139. }
  140.  
  141. extern unsigned int rd_unsigned2();
  142.  
  143. open_archive(name, mode)
  144. register char *name;
  145. register int mode;
  146. {
  147.   unsigned short magic = 0;
  148.   int fd;
  149.  
  150.   if (mode == CREATE) {
  151.     if ((fd = creat(name, 0644)) < 0)
  152.         error(TRUE, "cannot creat %s\n", name);
  153.     magic = MAGIC_NUMBER;
  154.     wr_int2(fd, magic);
  155.     return fd;
  156.   }
  157.  
  158.   if ((fd = open(name, mode)) < 0) {
  159.     if (mode == APPEND) {
  160.         close(open_archive(name, CREATE));
  161.         if (!nocr_fl) error(FALSE, "%s: creating %s\n", progname, name);
  162.         return open_archive(name, APPEND);
  163.     }
  164.     error(TRUE, "cannot open %s\n", name);
  165.   }
  166.   lseek(fd, 0L, 0);
  167.   magic = rd_unsigned2(fd);
  168.   if (magic != MAGIC_NUMBER)
  169.     error(TRUE, "%s is not in ar format\n", name);
  170.   
  171.   return fd;
  172. }
  173.  
  174. catch()
  175. {
  176.     unlink(temp_arch);
  177.     exit (2);
  178. }
  179.  
  180. main(argc, argv)
  181. int argc;
  182. char *argv[];
  183. {
  184.   register char *ptr;
  185.  
  186.   progname = argv[0];
  187.  
  188.   if (argc < 3)
  189.     usage();
  190.   
  191.   for (ptr = argv[1]; *ptr; ptr++) {
  192.     switch (*ptr) {
  193.         case 't' :
  194.             show_fl = TRUE;
  195.             break;
  196.         case 'v' :
  197.             verbose = TRUE;
  198.             break;
  199.         case 'x' :
  200.             ex_fl = TRUE;
  201.             break;
  202.         case 'a' :
  203.             app_fl = TRUE;
  204.             break;
  205.         case 'c' :
  206.             nocr_fl = TRUE;
  207.             break;
  208. #ifndef AAL
  209.         case 'p' :
  210.             pr_fl = TRUE;
  211.             break;
  212. #endif
  213.         case 'd' :
  214.             del_fl = TRUE;
  215.             break;
  216.         case 'r' :
  217.             rep_fl = TRUE;
  218.             break;
  219.         case 'l' :
  220.             local_fl = TRUE;
  221.             break;
  222. #ifdef DISTRIBUTION
  223.         case 'D' :
  224.             distr_fl = TRUE;
  225.             break;
  226. #endif
  227.         default :
  228.             usage();
  229.     }
  230.   }
  231. #ifdef DISTRIBUTION
  232.   if (distr_fl) {
  233.     struct stat statbuf;
  234.  
  235.     stat(progname, &statbuf);
  236.     distr_time = statbuf.st_mtime;
  237.   }
  238. #endif
  239.   if (local_fl) strcpy(temp_arch, "ar.XXXXXX");
  240.   else    strcpy(temp_arch, "/tmp/ar.XXXXXX");
  241.  
  242.   if (app_fl + ex_fl + del_fl + rep_fl + show_fl + pr_fl != 1)
  243.     usage();
  244.   
  245.   if (rep_fl || del_fl
  246. #ifdef AAL
  247.     || app_fl
  248. #endif
  249.      ) {
  250.     mktemp(temp_arch);
  251.   }
  252. #ifdef AAL
  253.   tab = (struct ranlib *) malloc(512 * sizeof(struct ranlib));
  254.   tstrtab = malloc(4096);
  255.   if (!tab || !tstrtab) error(TRUE,"Out of core\n");
  256.   tabsz = 512;
  257.   strtabsz = 4096;
  258. #endif
  259.  
  260.   signal(SIGINT, catch);
  261.   get(argc, argv);
  262.   
  263.   return 0;
  264. }
  265.  
  266. MEMBER *
  267. get_member()
  268. {
  269.   static MEMBER member;
  270.  
  271. again:
  272.   if (rd_arhdr(ar_fd, &member) == 0)
  273.     return NIL_MEM;
  274. #ifdef AAL
  275.   if (equal(SYMDEF, member.ar_name)) {
  276.     lseek(ar_fd, member.ar_size, 1);
  277.     goto again;
  278.   }
  279. #endif
  280.   return &member;
  281. }
  282.  
  283. char *get_mode();
  284.  
  285. get(argc, argv)
  286. int argc;
  287. register char *argv[];
  288. {
  289.   register MEMBER *member;
  290.   int i = 0;
  291.   int temp_fd, read_chars;
  292.  
  293.   ar_fd = open_archive(argv[2], (show_fl || pr_fl || ex_fl) ? READ : APPEND);
  294.   if (rep_fl || del_fl
  295. #ifdef AAL
  296.     || app_fl
  297. #endif
  298.   )
  299.     temp_fd = open_archive(temp_arch, CREATE);
  300.   while ((member = get_member()) != NIL_MEM) {
  301.     if (argc > 3) {
  302.         for (i = 3; i < argc; i++) {
  303.             if (equal(basename(argv[i]), member->ar_name))
  304.                 break;
  305.         }
  306.         if (i == argc || app_fl) {
  307.             if (rep_fl || del_fl
  308. #ifdef AAL
  309.                 || app_fl
  310. #endif
  311.             ) {
  312. #ifdef AAL
  313.                 if (i != argc) {
  314.                     printf("%s: already in archive\n", argv[i]);
  315.                     argv[i] = "";
  316.                 }
  317. #endif
  318.                 wr_arhdr(temp_fd, member);
  319.                 copy_member(member, ar_fd, temp_fd, 0);
  320.             }
  321.             else {
  322. #ifndef AAL
  323.                 if (app_fl && i != argc) {
  324.                     printf("%s: already in archive\n", argv[i]);
  325.                     argv[i] = "";
  326.                 }
  327. #endif
  328.                 lseek(ar_fd, even(member->ar_size),1);
  329.             }
  330.             continue;
  331.         }
  332.     }
  333.     if (ex_fl || pr_fl)
  334.         extract(member);
  335.     else {
  336.         if (rep_fl)
  337.             add(argv[i], temp_fd, "r - %s\n");
  338.         else if (show_fl) {
  339.             char buf[sizeof(member->ar_name) + 2];
  340.             register char *p = buf, *q = member->ar_name;
  341.  
  342.             while (q <= &member->ar_name[sizeof(member->ar_name)-1] && *q) {
  343.                 *p++ = *q++;
  344.             }
  345.             *p++ = '\n';
  346.             *p = '\0';
  347.             if (verbose) {
  348.                 char *mode = get_mode(member->ar_mode);
  349.                 char *date = ctime(&(member->ar_date));
  350.  
  351.                 *(date + 16) = '\0';
  352.                 *(date + 24) = '\0';
  353.  
  354.                 printf("%s%3u/%u%7D %s %s %s",
  355.                     mode,
  356.                     (unsigned) (member->ar_uid & 0377),
  357.                     (unsigned) (member->ar_gid & 0377),
  358.                     member->ar_size,
  359.                     date+4,
  360.                     date+20,
  361.                     buf);
  362.             }
  363.             else    printf(buf);
  364.         }
  365.         else if (del_fl)
  366.             show("d - %s\n", member->ar_name);
  367.         lseek(ar_fd, even(member->ar_size), 1);
  368.     }
  369.     argv[i] = "";
  370.   }
  371.  
  372.   if (argc > 3) {
  373.     for (i = 3; i < argc; i++)
  374.         if (argv[i][0] != '\0') {
  375. #ifndef AAL
  376.             if (app_fl)
  377.                 add(argv[i], ar_fd, "a - %s\n");
  378.             else
  379. #endif
  380.             if (rep_fl
  381. #ifdef AAL
  382.                 || app_fl
  383. #endif
  384.             )
  385.                 add(argv[i], temp_fd, "a - %s\n");
  386.             else {
  387.                 printf("%s: not found\n", argv[i]);
  388.             }
  389.         }
  390.   }
  391.  
  392.   if (rep_fl || del_fl
  393. #ifdef AAL
  394.         || app_fl
  395. #endif
  396.   ) {
  397.     signal(SIGINT, SIG_IGN);
  398.     close(ar_fd);
  399.     close(temp_fd);
  400.     ar_fd = open_archive(argv[2], CREATE);
  401.     temp_fd = open_archive(temp_arch, APPEND);
  402. #ifdef AAL
  403.     write_symdef();
  404. #endif
  405.     while ((read_chars = read(temp_fd, io_buffer, IO_SIZE)) > 0)
  406.         mwrite(ar_fd, io_buffer, read_chars);
  407.     close(temp_fd);
  408.     unlink(temp_arch);
  409.   }
  410.   close(ar_fd);
  411. }
  412.  
  413. add(name, fd, mess)
  414. char *name;
  415. int fd;
  416. char *mess;
  417. {
  418.   static MEMBER member;
  419.   register int read_chars;
  420.   struct stat status;
  421.   int src_fd;
  422.  
  423.   if (stat(name, &status) < 0) {
  424.     error(FALSE, "cannot find %s\n", name);
  425.     return;
  426.   }
  427.   else if ((src_fd = open(name, 0)) < 0) {
  428.     error(FALSE, "cannot open %s\n", name);
  429.     return;
  430.   }
  431.  
  432.   strncpy (member.ar_name, basename (name), sizeof(member.ar_name));
  433.   member.ar_uid = status.st_uid;
  434.   member.ar_gid = status.st_gid;
  435.   member.ar_mode = status.st_mode;
  436.   member.ar_date = status.st_mtime;
  437.   member.ar_size = status.st_size;
  438. #ifdef DISTRIBUTION
  439.   if (distr_fl) {
  440.     member.ar_uid = 2;
  441.     member.ar_gid = 2;
  442.     member.ar_mode = 0644;
  443.     member.ar_date = distr_time;
  444.   }
  445. #endif
  446.   wr_arhdr(fd, &member);
  447. #ifdef AAL
  448.   do_object(src_fd, member.ar_size);
  449.   lseek(src_fd, 0L, 0);
  450.   offset += AR_TOTAL + even(member.ar_size);
  451. #endif
  452.   while (status.st_size > 0) {
  453.     i